package com.train.mgr.modules.biz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.train.common.enums.LimitEnum;
import com.train.common.enums.UserTypeEnum;
import com.train.common.exception.BizException;
import com.train.common.exception.BusinessException;
import com.train.common.model.PageResult;
import com.train.common.utils.AuthUtils;
import com.train.mgr.modules.biz.dto.request.CustQueryReqDTO;
import com.train.mgr.modules.biz.dto.request.CustReqDTO;
import com.train.mgr.modules.biz.dto.response.CustDetailRespDTO;
import com.train.mgr.modules.biz.dto.response.CustListRespDTO;
import com.train.mgr.modules.biz.entity.Customer;
import com.train.mgr.modules.biz.mapper.CustomerMapper;
import com.train.mgr.modules.biz.service.CustomerService;
import com.train.mgr.modules.system.entity.User;
import com.train.mgr.modules.system.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Slf4j
@Service("customerService")
public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer> implements CustomerService {

    @Autowired
    private UserService userService;
   // @Autowired
   // private RoleService roleService;
   // @Autowired
    //private MenuService menuService;
   // @Autowired
   // private UserRoleService userRoleService;
  // @Autowired
   // private DeptService deptService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    private static final String COUNTER_KEY_PREFIX = "train:cacheCount:customerCount_";
    private static final String nickName = "企业管理员";
    @Override
    @Transactional
    public boolean add(CustReqDTO body){
        this.checkParam(body);
        Customer custBean = BeanUtil.copyProperties(body, Customer.class);
        custBean.setCompanyCode(body.getCompanyCode());//生成客户编码
        custBean.setCreateBy(AuthUtils.getNickname());
        int rows = this.baseMapper.insert(custBean);
        Long customerId = custBean.getId();
        //新建账号用户
        Long userId = this.saveOrUpdateAccount(customerId,body);
        log.info("add User account userId:{}",userId);
        //初始化用户的角色及建立关系。
       // Long roleId = this.saveUserRole(userId);
        //保存角色与菜单的关系。
      //  int result = roleService.saveMenu(roleId, body.getMenuIds());
        //初始化部门组织的根目录ID
       // deptService.insertDefaultDept(customerId,body.getCompanyName());
        //客户绑定授权职能项目
        //funProjectService.saveCustFunProject(body.getFunIds(),customerId);
        return rows >0;
    }

    @Override
    @Transactional
    public boolean update(CustReqDTO body){
        this.checkParam(body);   
        Customer customer = this.baseMapper.selectById(body.getId());
        if(ObjectUtil.isEmpty(customer)){
            throw new BusinessException("客户记录不存在～");
        }
        BeanUtil.copyProperties(body, customer);
        //更新客户基本信息
        int rows = this.baseMapper.updateById(customer);
        //更新账号用户信息
        Long userId = this.saveOrUpdateAccount(customer.getId(),body);
        log.info("update User account userId:{}",userId);
        //重新获取用户角色信息
       // long roleId = this.getUserRole(userId);
        //重新更新菜单信息（先删，后增）
       // int result = roleService.saveMenu(roleId,body.getMenuIds());
        //客户重新绑定授权职能项目
        //funProjectService.saveCustFunProject(body.getFunIds(),customer.getId());
        //更新部门表的TOP顶级部门名称（公司名称）
        //deptService.updateCompanyDeptName(body.getId(),body.getCompanyName());
        return rows >0;
    }

    /**
     * 查询详情
     * @param custId
     * @return
     */
    @Override
    public CustDetailRespDTO findById(Long custId){
        CustDetailRespDTO dto = new CustDetailRespDTO();
        Customer customer = this.baseMapper.selectById(custId);
        if(ObjectUtil.isEmpty(customer)){
            throw new BusinessException("客户记录不存在～");
        }
        BeanUtil.copyProperties(customer, dto);

        LambdaQueryWrapper<User> wrapper = Wrappers.<User>lambdaQuery()
                .eq(User::getCustomerId, customer.getId())
                .eq(User::getUserType, UserTypeEnum.ETP_USER.getCode())
                .eq(User::getUsername, customer.getCompanyCode())
                .eq(User::getIsEtpManager, 1);
        User user = userService.getOne(wrapper);
        if(ObjectUtil.isEmpty(user)){
            throw new BusinessException("管理账号信息异常～");
        }

        dto.setCustomerId(customer.getId());
        dto.setUsername(user.getUsername());
        dto.setNickName(user.getNickName());
        dto.setDeadlineTime(user.getDeadlineTime());
        dto.setUseLimit(user.getUseLimit());
        dto.setEnabled(user.getEnabled());
        dto.setCompanyCode(customer.getCompanyCode());
       // dto.setOriginalPwd(user.getOriginalPwd());
        return dto;
    }

    /**
     * 分页列表查询
     * @param params
     * @return
     */
    public PageResult<CustListRespDTO> page(CustQueryReqDTO params){
        Page<CustListRespDTO> page = params.buildPage();
        Page<CustListRespDTO> resultPage = baseMapper.selectCustListPage(page, params.getQ(),params.getEnable());
        return PageResult.of(resultPage, CustListRespDTO.class);
    }

    /**
     * 参数校验
     * @param body
     */
    private void checkParam(CustReqDTO body){
        if(LimitEnum.LIMIT.getCode().equals(body.getUseLimit()) && ObjectUtil.isEmpty(body.getDeadlineTime())){
            throw new BusinessException("截止时间不能为空～");
        }

        //校验企业客户名称重复的问题
        LambdaQueryWrapper<Customer> cwrapper = Wrappers.<Customer>lambdaQuery()
                .eq(Customer::getCompanyName, body.getCompanyName())
                .ne(body.getId()!=null && body.getId()>0,Customer::getId, body.getId())
                .eq(Customer::getIsDeleted, 0);
        long count = baseMapper.selectCount(cwrapper);
        if(count  >0 ){
            throw new BusinessException("企业客户名称重复,请重新输入～");
        }
        if (StrUtil.isBlank(body.getCompanyCode())){
            throw new BusinessException("企业码不能为空");
        }
        //校验用户是否存在
        //If 修改客户
        if(body.getId() != null && body.getId() > 0){
            LambdaQueryWrapper<User> wrapper = Wrappers.<User>lambdaQuery()
                    .eq(User::getUserType,UserTypeEnum.ETP_USER.getCode())
                    .eq(User::getCustomerId, body.getId())
                    .eq(User::getIsEtpManager, 1);
            User user = userService.getOne(wrapper);
            if(ObjectUtil.isEmpty(user)){
                throw new BusinessException("管理账号信息异常～");
            }
            if(ObjectUtil.isNotEmpty(user) && !user.getUsername().equals(body.getCompanyCode())){
                throw new BusinessException("管理账号不允许修改～");
            }
        }else{
//            if(body.getId()!=null && body.getId() ==0){
//                 throw new BusinessException("客户ID值有误～");
//            }
            LambdaQueryWrapper<User> wrapper = Wrappers.<User>lambdaQuery()
                    .eq(User::getUsername, body.getCompanyCode())
                    .eq(User::getUserType, UserTypeEnum.ETP_USER.getCode())
                    .eq(User::getIsEtpManager, 1);
            User user = userService.getOne(wrapper);
            if(ObjectUtil.isNotEmpty(user)){
                throw new BusinessException("管理账号已存在～");
            }
        }

//        if(ObjectUtil.isEmpty(body.getMenuIds()) || body.getMenuIds().size()<=0){
//            throw new BusinessException("功能权限不能为空～");
//        }
//        if(ObjectUtil.isNotEmpty(body.getMenuIds()) && body.getMenuIds().size()>0){
//            LambdaQueryWrapper<Menu> queryWrapper = Wrappers.<Menu>lambdaQuery()
//                    .in(Menu::getId, body.getMenuIds());
//           long menuCount = menuService.count(queryWrapper);
//           if(menuCount != body.getMenuIds().size()){
//               throw new BusinessException("功能权限参数值不正确～");
//           }
//           //如果选择了【功能权限->职能管理】 则需选择职能权限授权设定。
//
//           Set<Long> menuIdsSet = new HashSet<>(body.getMenuIds());
//           Long targetMenuId = MyConstant.BUSI_ID;//职能管理Id
//           boolean exists = menuIdsSet.contains(targetMenuId);
//           if(exists && CollUtil.isEmpty(body.getFunIds())){
//               throw new BusinessException("职能项目授权设定必须选择～");
//           }

  //      }
    }

    /**
     * 新建客户账号（建立与客户信息的关联）
     * @param customerId
     * @param body
     */
    private Long saveOrUpdateAccount(Long customerId,CustReqDTO body){
        //if修改客户信息
        if(body.getId()!=null && body.getId() >0){
            LambdaQueryWrapper<User> wrapper = Wrappers.<User>lambdaQuery()
                    .eq(User::getUserType,UserTypeEnum.ETP_USER.getCode())
                    .eq(User::getCustomerId, body.getId())
                    .eq(User::getIsEtpManager, 1);
            User user = userService.getOne(wrapper);
            user.setNickName(nickName);
            user.setEnabled(body.getEnabled());
            user.setDeptName(body.getCompanyName());
            user.setOriginalPwd(body.getCompanyCode());
            user.setPassword(passwordEncoder.encode(body.getCompanyCode()));
            user.setUseLimit(body.getUseLimit());
            user.setIsEtpManager(1);//企业管理员
            //UseLimit使用期限（0-永久，1-有截止时间）
//            if("1".equals(body.getUseLimit()) && StrUtil.isNotBlank(body.getDeadlineTime())){
//                user.setDeadlineTime(DateUtil.parse(body.getDeadlineTime(),"yyyy-MM-dd"));
//            }
            userService.updateById(user);
            return user.getId();
        }else{
            User user = new User();
            user.setDeptName(body.getCompanyName());
            user.setUsername(body.getCompanyCode());
            user.setCustomerId(customerId);
            user.setOriginalPwd(body.getCompanyCode());
            user.setPassword(passwordEncoder.encode(body.getCompanyCode()));
            user.setNickName(nickName);
            user.setEnabled(body.getEnabled());
            user.setUserType(UserTypeEnum.ETP_USER.getCode().toString()); //用户类型：企业管理人员
            user.setIsInitEtp(1);//是否初始化第一个企业管理者（1-是）
            user.setUseLimit(body.getUseLimit());
            user.setIsEtpManager(1);
            user.setEmpCheckState(1);//默认审核通过
            //UseLimit使用期限（0-永久，1-有截止时间）
            if("1".equals(body.getUseLimit()) && StrUtil.isNotBlank(body.getDeadlineTime())){
                user.setDeadlineTime(DateUtil.parse(body.getDeadlineTime(),"yyyy-MM-dd"));
            }
            userService.save(user);

            return user.getId();
        }
    }

    /**
     * 创建角色及对应的菜单关系

    private Long saveUserRole(Long userId){
        //企业管理默认角色-初始化
        Role role = new Role();
        role.setCode("default_role");
        role.setName("默认角色");
        role.setDataScope("全部");//数据范围（1：全部数据权限 2：自定数据权限 3：本部门数据权限 4：本部门及以下数据权限）
        role.setRoleCategory("3"); //角色分类(-运营管理用户，1-企业管理用户，3-全部可见）)
        role.setDescription("默认用户角色");
        roleService.save(role);
        Long roleId = role.getId();

        UserRole userRole = new UserRole();
        userRole.setUserId(userId);
        userRole.setRoleId(roleId);
        userRoleService.save(userRole);

        return roleId;
    }*/

    /**
     * 更新客户信息时，重新获取用户的角色信息
     * @param userId

    private long getUserRole(Long userId){
        //查询用户的角色（默认给的是一个角色）
        List<UserRole> userRoleList = userRoleService.findByUserId(userId);
        if(userRoleList == null || userRoleList.size() > 1){
            throw new BusinessException("功能权限数据异常～");
        }
        //当初初始化的时候就是赋予的一个默认角色（直接取一个）。
        UserRole userRole = userRoleList.get(0);
        //角色ID
        return userRole.getRoleId();
    }*/


    /**
     * 获取当年内的客户计数信息
     * @return
     */
    public String generateCustomerCode() {
        int currentYear = DateUtil.year(new Date());
        String counterKey = COUNTER_KEY_PREFIX + currentYear;
        // 使用INCR命令增加计数器，并获取新的值
        Long customerCount = redisTemplate.opsForValue().increment(counterKey, 1);
        // 格式化编号为当前年份+当前年份客户数
        return String.format("%s%04d", currentYear, customerCount);
    }


    @Override
    public User findUserByCustId(Long custId){
        LambdaQueryWrapper<User> wrapper = Wrappers.<User>lambdaQuery()
                .eq(User::getCustomerId, custId)
                .eq(User::getIsEtpManager, 1)
                .eq(User::getUserType, UserTypeEnum.ETP_USER.getCode());
        User user = userService.getOne(wrapper);
        if(ObjectUtil.isEmpty(user)){
            throw new BusinessException("管理账号信息异常～");
        }
        return user;
    }


    /**
     * 员工注册-免审核模式
     * 账号是否免审核模式（0：否，1：是
     * @param customerId
     * @param checkMode
     * @return
     */
    @Override
    public boolean setEmpCheckMode(Long customerId, Integer checkMode){
        Customer customer = this.baseMapper.selectById(customerId);
        if(ObjectUtil.isEmpty(customer)){
            throw new BusinessException("客户记录不存在～");
        }

        if (checkMode == null || ( 0 != checkMode && 1 != checkMode)) {
            throw new BizException("checkMode参数不正确");
        }
        customer.setCheckMode(checkMode);//1-需审核，0-无需审核
        customer.setUpdateBy(AuthUtils.getNickname());
        customer.setUpdateTime(new Date());
        int result = baseMapper.updateById(customer);
        boolean bool = result >0 ? true : false;
        return bool;
    }

    @Override
    public Boolean checkCustomerCode(String code) {
        LambdaQueryWrapper<Customer> wrapper = Wrappers.<Customer>lambdaQuery()
                .eq(Customer::getIsDeleted, 0)
                .eq(Customer::getCompanyCode, code);
        return this.baseMapper.selectCount(wrapper) > 0;
    }
}
